package org.infoset.xml.memory;

import java.util.*;
import java.io.*;
import java.net.*;

import org.infoset.xml.*;


public class MemoryDocument extends MemoryParent implements Document {

   protected boolean standalone;
   protected String version;
   protected Element docElement;
   protected Map elementMap;
   protected String encoding;
   
   private MemoryDocument(URI base,MemoryElement top,Infoset context) {
      super(context,0,base,null);
      this.docElement = top;
      if (docElement!=null) {
         super.add(docElement);
      }
      this.elementMap = null;
      this.standalone = true;
      this.version = "1.0";
      this.encoding = "UTF-8";
   }

   public MemoryDocument(URI base,Infoset context) {
      super(context,0,base,null);
      docElement = null;
   }
   
   public Item copyOfItem(boolean copyAll) {
      MemoryDocument d = new MemoryDocument(baseURI,null,infoset);
      if (copyAll) {
         for (Child c : this) {
            d.add((Child)c.copyOfItem(copyAll));
         }
      }
      return d;
   }
   
   public boolean isStandalone() {
      return standalone;
   }
   
   public void setStandalone(boolean flag) {
      standalone = flag;
   }
   
   public String getVersion() {
      return version;
   }
   
   public void setVersion(String version) {
      this.version = version;
   }
   
   public String getEncoding() {
      return encoding;
   }

   public void setEncoding(String encoding) {
      this.encoding = encoding;
   }
   
   public URI getBaseURI() {
      return baseURI;
   }

   public void setBaseURI(URI base) {
      baseURI = base;
   }

   protected void setIndex(int index) {
   }

   public ItemType getType() {
      return ItemType.DocumentItem;
   }

   public Element getDocumentElement() {
      return docElement;
   }

   public NamespaceScope getNamespaceScope() {
      return docElement!=null ? docElement.getNamespaceScope() : null;
   }

   public Element createDocumentElement(Name name) { 
      docElement = new MemoryElement(infoset,null,this,name);
      super.add(docElement);
      return docElement;
   }

   public Element createDocumentElement(String localName) { 
      docElement = new MemoryElement(infoset,null,this,infoset.createName(localName));
      super.add(docElement);
      return docElement;
   }

   public boolean add(Child n) {
      if (n instanceof Element) {
         if (docElement==null) {
            docElement = (Element)n;
         } else {
            throw new IllegalStateException("The document element has already been set for the document.");
         }
      }
      return super.add(n);
   }

   public Element getElementWithId(String id) { 
      return elementMap==null ? null : (Element)elementMap.get(id);
   }
   
   public Child getFollowingSibling() {
      return null;
   }
   
   public Child getPrecedingSibling() {
      return null;
   }

   /*
   public Object clone() {
      // TODO: need to clone the other children
      return new MemoryDocument(baseURI,(MemoryElement)docElement.clone(),infoset);
   }*/
   
   public Iterator getFollowingSiblings() {
      return Collections.EMPTY_LIST.iterator();
   }
   
   public Iterator getPrecedingSiblings() {
      return Collections.EMPTY_LIST.iterator();
   }
   
   public int getColumn() {
      return 1;
   }
   
   public int getLine() {
      return 1;
   }
   
   public void setColumn(int column) {
      if (column!=1) {
         throw new IllegalArgumentException("Documents must start at column 1.");
      }
   }
   
   public void setLine(int line) {
      if (line!=1) {
         throw new IllegalArgumentException("Documents must start at line 1.");
      }
   }
   
   public String toString() {
      return "[document "+baseURI+" ]";
   }
   
}

